package com.crazypie.soundgraph 
{
	import flash.events.Event;
	import flash.media.Sound;
	import flash.media.SoundTransform;
	
	/**
	 * ...
	 * @author Paul Pepper
	 */
	public interface ISoundNode 
	{
		/**
		 * Add a child sound node.
		 * Will remove supplied node from any other graphs they currently belong to
		 * @param	child
		 */
		function addChild( child:ISoundNode ):void
		
		/**
		 * Remove a child node
		 * 
		 * @param	child
		 * @return the removed node, or null if supplied node was not a child of the node
		 */
		function removeChild( child:ISoundNode ):ISoundNode
		
		/**
		 * Remove the child at the numbered position
		 * @param	position
		 * @return the removed node, or null if no node at supplied position
		 */
		function removeChildAt( position:uint ):ISoundNode
		
		/**
		 * returns the ISoundNode object at the supplied position
		 * 
		 * @param	childIndex
		 * @return
		 */
		function getChildAt( childIndex:uint ):ISoundNode
		
		/**
		 * returns the number of children this node has
		 */
		function get numChildren():uint
		
		/**
		 * Sets this node's parent. If null, sets to no parent
		 */
		function setParent( newParent:ISoundNode ):void
		
		/**
		 * returns the parent sound node, or null if there is no parent
		 */
		function get parent():ISoundNode
		
		//sound methods
		
		/**
		 * Plays the attached sound
		 * 
		 * @param	startTime
		 * @param	loops to play - 0=loop infinitely
		 */
		function play( startTime:Number = 0, loops:uint = 1 ):void
		
		/**
		 * Plays the attached sound, and will clear once complete
		 * 
		 * @param	startTime
		 * @param	loops to play - 0=loop infinitely (will never clear itself)
		 */
		function playAndClear( startTime:Number = 0, loops:uint = 1 ):void
		
		/**
		 * Plays the attached sound, and will destroy it once complete
		 * 
		 * @param	startTime
		 * @param	loops to play - 0=loop infinitely (will never clear itself)
		 */
		function playAndDestroy( startTime:Number = 0, loops:uint = 1 ):void
		
		/**
		 * stops any playing sound
		 */
		function stop():void
		
		/**
		 * returns if this node is set to play (is not affected by the pause property)
		 * @return
		 */
		function get isPlaying():Boolean
		
		/**
		 * returns/sets if this sound node is paused
		 * Will not return true if ancestor node has pauseChildren = true
		 */
		function get pause():Boolean
		
		function set pause( newPause:Boolean ):void
		
		/**
		 * Returns/sets if this node has pauseChildren set to true
		 * Will not return if ancestor node has pauseChildren set to true
		 */
		function get pauseChildren():Boolean
		
		function set pauseChildren( newPauseChildren:Boolean ):void
		
		/**
		 * stops all descendent nodes from playing sound
		 */
		function stopChildren():void
		
		/**
		 * Returns the position in the sound that is being played in milliseconds.
		 * Includes loops, e.g. a 1 second sound polaying 3 loops will return 1500 when it is half way through the second loop
		 */
		function get position():Number
		
		/**
		 * seeks to a position within the sound, including across loops
		 * 
		 * @param	position - the time in milliseconds to move to
		 */
		function set position( newPosition:Number ):void
		
		/**
		 * returns the total length of the sound in milliseconds (including loops)
		 * will return POSITIVE_INFINITY for infinitely looped sounds
		 * and 0 for nodes with no sound attached
		 */
		function get duration():Number
		
		/**
		 * returns the length of a single loop of a sound in milliseconds.
		 * Will return 0 for nodes with no sound attached
		 */
		function get loopDuration():Number
		
		/**
		 * Returns how long this sound has left to play in milliseconds.
		 * Will return 0 if no sound attached, or sound is not playing
		 * (is not affected by pause status)
		 */
		function get remainingTime():Number
		
		/**
		 * How many loops this sound has been set to play
		 * will default to 1
		 */
		function get loops():uint
		
		/**
		 * Change the number of loops this sound should play for
		 */
		function set loops( newLoops:uint ):void
		
		/**
		 * returns how many loops this sound has left to play.
		 * May return a number such as 3.245. May return 0 if no sound attasched, or not playing (not affected by pause)
		 */
		function get remainingLoops():Number
		
		/**
		 * specify what sound this node plays
		 */
		function set sound( newSound:Sound ):void
		
		/**
		 * returns what sound this node is playing
		 */
		function get sound():Sound
		
		/**
		 * Will stop the sound this node is playing, and totally remove any sound information
		 * Will not affect children
		 */
		function clear():void
		 
		/**
		 * perform tidyup - will totally destory this node and all of it's children ready for garbage collection
		 */
		function destroy():void
		
		//transform methods
		
		function get transform():SoundTransform
		
		function set transform( newTransform:SoundTransform ):void
		
		function get computedTransform():SoundTransform
		
		function set parentTransform( newParentTransform:SoundTransform ):void;
		
		//audio transform helper functions
		
		function get leftToLeft():Number
		
		function set leftToLeft( newLeftToLeft:Number ):void
		
		function get leftToRight():Number
		
		function set leftToRight( newLeftToLeft:Number ):void
		
		function get rightToLeft():Number
		
		function set rightToLeft( newRightToLeft:Number ):void
		
		function get rightToRight():Number
		
		function set rightToRight( newRightToRight:Number ):void
		
		function get pan():Number
		
		function set pan( newPan:Number ):void
		
		function get volume():Number
		
		function set volume( newVolume:Number ):void
		
		function changeVolume( changeBy:Number ):void
		
		/**
		 * Gets mute status of this node. Will return true even if a ancestor node is muted
		 */
		function get mute():Boolean
		
		/**
		 * Sets the mute status for this node. Will render this node and all if it's descendants silent
		 * but will not change their mute property
		 */
		function set mute( newMute:Boolean ):void
		
		//Event dispatcher functions
		
		/**
		 * Registers an event listener object with an EventDispatcher object so that the listener receives notification of an event.
		 * 
		 * @param	type
		 * @param	listener
		 * @param	useCapture
		 * @param	priority
		 * @param	useWeakReference
		 */
		function addEventListener (type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false) : void;
		
		/**
		 * Dispatches an event into the event flow.
		 * 
		 * @param	event
		 * @return
		 */ 
		function dispatchEvent (event:Event) : Boolean;
		
		/**
		 * Checks whether the EventDispatcher object has any listeners registered for a specific type of event.
		 * 
		 * @param	type
		 * @return
		 */
		function hasEventListener (type:String) : Boolean;
		
		/**
		 * Removes a listener from the EventDispatcher object.
		 * 
		 * @param	type
		 * @param	listener
		 * @param	useCapture
		 */
		function removeEventListener (type:String, listener:Function, useCapture:Boolean = false) : void;
		
		//public function toString () : String;
		
		/**
		 * Checks whether an event listener is registered with this EventDispatcher object or any of its ancestors for the specified event type.
		 * 
		 * @param	type
		 * @return
		 */
		function willTrigger (type:String) : Boolean;
		
	}
	
}